package com.cloudfun.campusshare.schedule;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StopWatch;

import java.util.concurrent.TimeUnit;

/**
 * Created by Huqin on 2020/6/1
 */
@Slf4j
public abstract class BaseScheduleTask {

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final String LOCK_PREFIX = "SCHEDULE_TASK_LOCK_";

    /**
     * 获取任务名称
     *
     * @return
     */
    protected abstract String getTaskName();

    /**
     * 执行任务
     */
    protected abstract void doExecute();

    /**
     * 执行任务
     */
    public void execute() {
        String taskName = this.getTaskName();
        String simpleName = this.getClass().getSimpleName();
        String key = LOCK_PREFIX + simpleName;
        Boolean locked = false;
        try {
            // 获取锁
            locked = redisTemplate.opsForValue().setIfAbsent(key, key, 10, TimeUnit.MINUTES);
            if (BooleanUtils.isTrue(locked)) {
                // 获取到了锁 执行任务
                log.info("开始执行【{}】定时任务", taskName);
                StopWatch stopWatch = new StopWatch();
                stopWatch.start(taskName);

                // 执行任务
                this.doExecute();

                stopWatch.stop();
                log.info("执行【{}】定时任务完成", taskName);
                log.info(stopWatch.prettyPrint());
            } else {
                // 没有获取到锁
                log.info("没有获取到任务：【{}】的锁，不执行任务", taskName);
            }
        } finally {
            if (BooleanUtils.isTrue(locked)) {
                // 如果获取到了锁则放锁
                redisTemplate.delete(key);
                log.info("任务：【{}】结束，释放锁", taskName);
            }
        }

    }

}
